package com.wxy;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.*;
import cn.hutool.http.webservice.SoapClient;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * http客户端命令行工具类
 *
 * @author wangxiaoyuan
 * 2021/7/8 11:33
 **/
public class Main {

    private static final String DATA_DELIMITER = ";";
    private static final String PARAM_PAIR_DELIMITER = "=";
    private static final String HEADER_PAIR_DELIMITER = ":";

    public static void main(String[] args) {
        // 程序终止时给出关闭提示
        Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Shutdown...")));
        // 主逻辑
        System.out.println("========================== Http Command Line Program ==========================");
        System.out.println("Eg:                                                                            ");
        System.out.println("1.http -url[url] -H[k:v] -form[k=v] -data[json] -m[method] -f[path] -name[name]");
        System.out.println("2.soap -url[url] -param[k=v] -method[method] -web[namespace]                   ");
        System.out.println("===============================================================================");
        Scanner scan = new Scanner(System.in);
        while (true) {
            try {
                System.out.println("Please enter the http command: [Enter 'exit' to exit]");
                String nextLine = scan.nextLine().trim();
                if (nextLine.startsWith("exit")) {
                    System.out.println("The program is about to exit.");
                    break;
                } else if (nextLine.startsWith("http")) {
                    // 解析参数
                    String header = ReUtil.getGroup1("-H\\[(.*?)\\]", nextLine);
                    String method = ReUtil.getGroup1("-m\\[(.*?)\\]", nextLine);
                    String data = ReUtil.getGroup1("-data\\[(.*?)\\]", nextLine);
                    String form = ReUtil.getGroup1("-form\\[(.*?)\\]", nextLine);
                    String url = ReUtil.getGroup1("-url\\[(.*?)\\]", nextLine);
                    String file = ReUtil.getGroup1("-f\\[(.*?)\\]", nextLine);
                    String name = ReUtil.getGroup1("-name\\[(.*?)\\]", nextLine);
                    Map<String, String> headers = new HashMap<>();
                    if (!StrUtil.isBlank(header)) {
                        String[] pairArr = header.split(DATA_DELIMITER);
                        for (String pair : pairArr) {
                            String[] split = pair.split(HEADER_PAIR_DELIMITER);
                            if (split.length == 2) {
                                headers.put(split[0], split[1]);
                            }
                        }
                    }
                    Map<String, Object> formMap = new HashMap<>();
                    if (StrUtil.isNotBlank(form)) {
                        String[] pairArr = form.split(DATA_DELIMITER);
                        for (String pair : pairArr) {
                            String[] split = pair.split(PARAM_PAIR_DELIMITER);
                            if (split.length == 2) {
                                formMap.put(split[0], split[1]);
                            }
                        }
                    }
                    if (StrUtil.isNotBlank(file)) {
                        formMap.put(StrUtil.isNotBlank(name) ? name : "file", FileUtil.file(file.split(DATA_DELIMITER)));
                    }
                    if (StrUtil.isNotBlank(url)) {
                        HttpRequest httpRequest = HttpUtil.createRequest(Method.valueOf(method.toUpperCase()), url);
                        // 设置请求头
                        if (!headers.isEmpty()) {
                            httpRequest.headerMap(headers, true);
                        }
                        // 设置from参数
                        if (!formMap.isEmpty()) {
                            httpRequest.form(formMap);
                        }
                        // 设置body参数
                        if (StrUtil.isNotBlank(data)) {
                            httpRequest.body(data);
                        }
                        // 设置默认配置
                        httpRequest.setConnectionTimeout(20000).setFollowRedirects(true).enableDefaultCookie();
                        // 发送请求
                        HttpResponse httpResponse = httpRequest.execute();
                        // 502 504 重试
                        int retry = 0;
                        while (retry++ < 3 && (httpResponse.getStatus() == HttpStatus.HTTP_GATEWAY_TIMEOUT
                                || httpResponse.getStatus() == HttpStatus.HTTP_UNAVAILABLE
                                || httpResponse.getStatus() == HttpStatus.HTTP_BAD_GATEWAY)) {
                            httpResponse = httpRequest.execute();
                        }
                        System.out.println("----");
                        // 解析响应
                        if (httpResponse.isOk()) {
                            System.out.println(httpResponse.body());
                        } else {
                            System.out.println(httpResponse);
                        }
                        System.out.println("----");
                    } else {
                        System.out.println("-url[url] is required!");
                    }
                } else if (nextLine.startsWith("soap")) {
                    // 解析参数
                    String url = ReUtil.getGroup1("-url\\[(.*?)\\]", nextLine);
                    String method = ReUtil.getGroup1("-method\\[(.*?)\\]", nextLine);
                    String param = ReUtil.getGroup1("-param\\[(.*?)\\]", nextLine);
                    String namespace = ReUtil.getGroup1("-web\\[(.*?)\\]", nextLine);

                    Map<String, Object> paramMap = new HashMap<>();
                    if (!StrUtil.isBlank(param)) {
                        String[] pairArr = param.split(DATA_DELIMITER);
                        for (String pair : pairArr) {
                            String[] split = pair.split(PARAM_PAIR_DELIMITER);
                            if (split.length == 2) {
                                paramMap.put(split[0], split[1]);
                            }
                        }
                    }
                    SoapClient client = SoapClient.create(url).setMethod("web:" + method, namespace).setParams(paramMap);
                    System.out.println("----");
                    System.out.println(client.send(true));
                    System.out.println("----");
                } else {
                    System.out.println("Unrecognized command!");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        scan.close();
        System.out.println("Shutdown...");
    }
}
